package com.bjzh.bjzh.servers;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import com.bjzh.bjzh.bean.JT809Constants;
import com.bjzh.bjzh.bean.Message;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.timeout.ReadTimeoutHandler;
import lombok.Getter;
import lombok.Setter;

import java.io.UnsupportedEncodingException;
import java.util.concurrent.TimeUnit;

/**
 * 从链路
 *
 * @author liuliwen
 */
@Getter
@Setter
public class Jtt809NettyClient implements Runnable {

    private static String ip = "117.149.227.64";
//        private static String ip = "183.129.170.218";

    private static int port = 25301;
//    private static int port = 25010;


    private static Channel channel;

    static {

        Jtt809NettyServer jtt809NettyServer = new Jtt809NettyServer(56731);
        Thread thread2 = new Thread(jtt809NettyServer);
        thread2.start();
        NettyServer nettyServer = new NettyServer();
        Thread thread = new Thread(nettyServer);
        thread.start();
    }
    public void sendLoginMessage() {
        Message message = new Message(JT809Constants.UP_CONNECT_REQ, 1213);
        ByteBuf body = Unpooled.buffer(46);
        body.writeInt(10001);
        body.writeBytes("88888888".getBytes());
        byte[] ipBytesource = "222.244.144.181".getBytes();
        byte[] ipByte = Jtt809Util.rightComplementByte(ipBytesource, 32);
        body.writeBytes(ipByte);
        body.writeShort(56831);
        message.setMsgBody(body);
        System.err.println("开始登陆");
        Jtt809Util.sendClientMessage(channel, message);
        System.err.println("发送登陆完毕");
    }

    public static void sendLinkTestMessage() {
        Message message = new Message(JT809Constants.UP_LINKETEST_REQ, 1213);
        ByteBuf body = Unpooled.buffer(26);
        message.setMsgBody(body);
        System.err.println("发送链接保持请求");
        Jtt809Util.sendClientMessage(getChannel(), message);
    }


    public static void reconn() {

        Channel channel = getChannel();
        if (ObjectUtil.isNull(channel)||(!channel.isActive())||(!channel.isWritable())){
            System.err.println("重新链接");
            reconn();
        }

    }


public static void sendLocationMessage(JSONObject jsonObject){
        //  {"altitude":0,"gps_time":1567998086,"distance":78085,"city_code":"150600","time_next":0,"next_station_no":12,"lon":"109.965417",
        //{"lng":120.699832,"dir":300,"speed":620,"carnumber":"浙CM1756","time":"2021-12-10 09:54:37","lat":27.718806,"status":1}
        // "dis_next":50,"line_id":173,"speed":21,"dev_sn":"","dev_id":285,"angle":179,"company_code":"76","vehicle_status":11,"lat":"39.810305","direction":1}

        //GPS信息
        String carnumber=jsonObject.get("carnumber").toString();
        System.err.println(carnumber);
        String time=jsonObject.get("time").toString();
        String lng=jsonObject.get("lng").toString();
        String lat=jsonObject.get("lat").toString();
        String speed=jsonObject.get("speed").toString();
        String dir=jsonObject.get("dir").toString();
        String status=jsonObject.get("status").toString();

        Message message=new Message(JT809Constants.UP_EXG_MSG,1213);

        ByteBuf buffer=Unpooled.buffer(64);
        byte[]deviceId=new byte[0];
        try{
        deviceId=(carnumber).getBytes("GBK");
        }catch(UnsupportedEncodingException e){
        e.printStackTrace();
        }
        byte[]ipByte=Jtt809Util.rightComplementByte(deviceId,21);
        buffer.writeBytes(ipByte);
        buffer.writeByte(02);//1
        buffer.writeShort(JT809Constants.UP_EXG_MSG_REAL_LOCATION);
        buffer.writeInt(36);//4
        buffer.writeByte(00);//1
        //date
        String[]s=time.split(" ");
        String[]dates=s[0].split("-");
        String[]times=s[1].split(":");
        buffer.writeByte(Integer.parseInt(dates[2]));//1
        buffer.writeByte(Integer.parseInt(dates[1]));//1
        buffer.writeShort((short)Integer.parseInt(dates[0]));//2
        //     2021-12-10 10:15:51
        //time 20211210101551
        buffer.writeByte(Integer.parseInt(times[0]));//1
        buffer.writeByte(Integer.parseInt(times[1]));//1
        buffer.writeByte(Integer.parseInt(times[2]));//1
        //
        buffer.writeInt((int)(Double.parseDouble(lng)*1000000));//4
        buffer.writeInt((int)(Double.parseDouble(lat)*1000000));//4
        buffer.writeShort((short)Integer.parseInt(speed));//2
        buffer.writeShort((short)0);//2
        buffer.writeInt(0);//4
        buffer.writeShort((short)Integer.parseInt(dir));//2
        buffer.writeShort((short)0);//2
        buffer.writeInt(Integer.parseInt("1"+status));//4
        buffer.writeInt(0);//4

        message.setMsgBody(buffer);
        Jtt809Util.sendClientMessage(getChannel(),message);
        }

public static Channel getChannel(){

    if (ObjectUtil.isNull(channel)||(!channel.isActive())||(!channel.isWritable())){
        int a=0x5d;
final ByteBuf delimiter=Unpooled.buffer(1);
        delimiter.writeByte(a);
        Bootstrap bootstrap=new Bootstrap();
        NioEventLoopGroup group=new NioEventLoopGroup();
        bootstrap.group(group)
        .channel(NioSocketChannel.class)
        .handler(new ChannelInitializer<Channel>(){
@Override
protected void initChannel(Channel ch){
        ch.pipeline().addLast(new ReadTimeoutHandler(300));//5分钟没有消息断开
        ch.pipeline().addLast(new DelimiterBasedFrameDecoder(5000,delimiter));
        ch.pipeline().addLast(new Jtt809Decoder());//该处理器将信息转换成message对象
        ch.pipeline().addLast(new Jtt809Handler());
        }
        });
        channel=bootstrap.connect(ip,port).channel();

        while(!channel.isActive()){
        try{
        TimeUnit.SECONDS.sleep(1);
        }catch(InterruptedException e){
        e.printStackTrace();
        }
        continue;
        }
        Message message=new Message(JT809Constants.UP_CONNECT_REQ,1213);
        ByteBuf body=Unpooled.buffer(46);
        body.writeInt(10001);
        body.writeBytes("88888888".getBytes());
        byte[]ipBytesource="222.244.144.181".getBytes();
        byte[]ipByte=Jtt809Util.rightComplementByte(ipBytesource,32);
        body.writeBytes(ipByte);
        body.writeShort(56831);
        message.setMsgBody(body);
        System.err.println("ssss开始登陆");
        Jtt809Util.sendClientMessage(channel,message);
        }
        return channel;
        }

private static byte[]getdate(){
        byte[]bb=new byte[4];
        bb[2]=0x07;
        bb[3]=(byte)0xD9;
        bb[1]=0x01;
        bb[0]=0x01;
        return bb;
        }

private static byte[]getTime(){
        byte[]bb=new byte[3];
        bb[2]=0x07;
        bb[1]=0x01;
        bb[0]=0x01;
        return bb;
        }

public static String getIp(){
        return ip;
        }

public static int getPort(){
        return port;
        }


@Override
public void run(){
        int a=0x5d;
final ByteBuf delimiter=Unpooled.buffer(1);
        delimiter.writeByte(a);
        Bootstrap bootstrap=new Bootstrap();
        NioEventLoopGroup group=new NioEventLoopGroup();
        bootstrap.group(group)
        .channel(NioSocketChannel.class)
        .handler(new ChannelInitializer<Channel>(){
@Override
protected void initChannel(Channel ch){
        ch.pipeline().addLast(new ReadTimeoutHandler(300));//5分钟没有消息断开
        ch.pipeline().addLast(new DelimiterBasedFrameDecoder(5000,delimiter));
        ch.pipeline().addLast(new Jtt809Decoder());//该处理器将信息转换成message对象
        ch.pipeline().addLast(new Jtt809Handler());
        }
        });
        System.err.println(ip);
        System.err.println(port);
        channel=bootstrap.connect(ip,port).channel();
        while(!channel.isActive()){
        try{
        TimeUnit.SECONDS.sleep(1);
        }catch(InterruptedException e){
        e.printStackTrace();
        }
        continue;
        }

        //发送一条登陆消息
        System.err.println("尝试登陆");
        sendLoginMessage();


        }
        }
